﻿using System;
using System.Collections.Generic;
using System.ComponentModel;
using System.Drawing;
using System.Data;
using System.Text;
using System.Windows.Forms;
using System.Globalization;
using TexasHoldEmCroupier.Enumerators;
using TexasHoldEmCroupier.Properties;
using TexasHoldEmCroupier.Views;

namespace TexasHoldEmCroupier.UserControls
{
    public partial class PlayerStrip : UserControl
    {
        #region Members
        private bool _IsDealer = false;
        private Blind _Blind = Blind.None;
        private string _PlayerName = String.Empty;
        private decimal _Account = 1000;
        private decimal _Stake = -1;
        private Action _Action = Action.None;
        private bool _IsActive = false;
        private bool _IsAvailable = true;
        #endregion

        #region Properties
        public bool IsDealer
        {
            get { return this._IsDealer; }
            set
            {
                if (!this._IsDealer.Equals(value))
                {
                    this._IsDealer = value;

                    this._imageStatus.Image = null;

                    if (this._IsDealer)
                    {
                        this._imageStatus.Image =
                            Resources.dealer;
                    }

                    if (this._Blind.Equals(Blind.Little))
                    {
                        this._imageStatus.Image =
                            this._IsDealer
                            ? Resources.dealer_little_blind
                            : Resources.little_blind;
                    }
                }
            }
        }

        public Blind Blind
        {
            get { return this._Blind; }
            set
            {
                if (!this._Blind.Equals(value))
                {
                    this._Blind = value;

                    this._imageStatus.Image = null;

                    if (this._IsDealer)
                    {
                        this._imageStatus.Image =
                            Resources.dealer;
                    }

                    if (this._Blind.Equals(Blind.Little))
                    {
                        this._imageStatus.Image =
                            this._IsDealer
                            ? Resources.dealer_little_blind
                            : Resources.little_blind;
                    }

                    if (this._Blind.Equals(Blind.Big))
                    {
                        this._imageStatus.Image =
                            Resources.big_blind;
                    }
                }
            }
        }

        public string PlayerName
        {
            get { return this._PlayerName; }
            set
            {
                if (!this._PlayerName.Equals(value))
                {
                    this._PlayerName = value;
                    this._labelName.Text = value;
                }
            }
        }

        public decimal Account
        {
            get { return this._Account; }
            set
            {
                if (!this._Account.Equals(value))
                {
                    this._Account = value;
                    this._labelAccount.Text = String.Format(
                        CultureInfo.CurrentCulture,
                        "{0:N2}",
                        value);
                    this._updownBet.Maximum = value;
                }
            }
        }

        public decimal Stake
        {
            get { return this._Stake; }
            set
            {
                if (!this._Stake.Equals(value))
                {
                    this._Stake = value;
                    this._labelStake.Text = String.Format(
                        CultureInfo.CurrentCulture,
                        "{0:N2}",
                        value);
                }
            }
        }

        public decimal Bet
        {
            get
            {
                return Convert.ToDecimal(
                    this._updownBet.Value,
                    CultureInfo.CurrentCulture);
            }
        }

        public Action Action
        {
            get { return this._Action; }
            set
            {
                if (!this._Action.Equals(value))
                {
                    this._Action = value;

                    switch (this._Action)
                    {
                        case Action.Check:
                            this._buttonAction.Text = "&Check";
                            break;
                        case Action.Bet:
                            this._buttonAction.Text = "&Bet";
                            break;
                        case Action.Raise:
                            this._buttonAction.Text = "&Raise";
                            break;
                        case Action.Call:
                            this._buttonAction.Text = "&Call";
                            break;
                        default:
                            this.BackColor = Color.DarkGreen;
                            break;
                    }
                }
            }
        }

        public bool IsAvailable
        {
            get { return this._IsAvailable; }
            set { this._IsAvailable = value; }
        }

        public bool IsActive
        {
            get { return this._IsActive; }
            set { this._IsActive = value; }
        }
        #endregion

        #region Methods
        public PlayerStrip()
        {
            InitializeComponent();
        }

        public PlayerStrip(
            string theName,
            decimal theAccount)
        {
            InitializeComponent();

            this.PlayerName = theName;
            this.Account = theAccount;
            this.Stake = 0;

            this.Disable();
        }

        #region Event Handlers
        private void _buttonFold_Click(object sender, EventArgs e)
        {
            this.Action = Action.Fold;

            this._labelName.ForeColor =
                this._labelAccount.ForeColor =
                this._labelStake.ForeColor = 
                    Color.Black;

            if (null != this.OnFold)
            {
                this.OnFold(this, new EventArgs());
            }
        }

        private void _updownBet_ValueChanged(object sender, EventArgs e)
        {
            if (this._updownBet.Value > this._updownBet.Minimum)
            {
                switch (this._Action)
                {
                    case Action.Check:
                    case Action.Bet:
                        this.Action = Action.Bet;
                        break;
                    case Action.Call:
                        this.Action = Action.Raise;
                        break;
                }
            }
            else
            {
                switch (this._Action)
                {
                    case Action.Bet:
                        this.Action = Action.Check;
                        break;
                    case Action.Raise:
                        this.Action = Action.Call;
                        break;
                }
            }
        }
        
        private void _buttonAction_Click(object sender, EventArgs e)
        {
            switch (this._Action)
            {
                default:
                    this.Action = Action.Call;
                    if (null != this.OnCall)
                    {
                        this.OnCall(this, new EventArgs());
                    }
                    break;
                case Action.Check:
                    this.Action = Action.Check;
                    if (null != this.OnCheck)
                    {
                        this.OnCheck(this, new EventArgs());
                    }
                    break;
                case Action.Bet:
                    this.Action = Action.Bet;
                    if (null != this.OnBet)
                    {
                        this.OnBet(this, new EventArgs());
                    }
                    break;
                case Action.Raise:
                    this.Action = Action.Raise;
                    if (null != this.OnRaise)
                    {
                        this.OnRaise(this, new EventArgs());
                    }
                    break;
            }
        }

        private void _buttonAllIn_Click(object sender, EventArgs e)
        {
            this.Action = Action.AllIn;

            if (null != this.OnAllIn)
            {
                this.OnAllIn(this, new EventArgs());
            }
        }
        #endregion

        #region Private Helpers
        public void Activate(
            MainView theParentView)
        {
            this._updownBet.Minimum = theParentView.CurrentBet - this.Stake;
            this._updownBet.Value = theParentView.CurrentBet - this.Stake;

            this.Enable();

            if (theParentView.CurrentBet.Equals(0))
            {
                this.Action = Action.Check;

                if (!theParentView.NumberOfAllInPlayers.Equals(0))
                {
                    this._updownBet.Visible =
                        this._buttonAllIn.Visible =
                            false;
                }
            }
            else if (theParentView.CurrentBet > this.Account)
            {
                this._updownBet.Visible = 
                    this._buttonAction.Visible =
                        false;
            }
            else if (theParentView.CurrentBet <= this.Account &&
                !theParentView.NumberOfAllInPlayers.Equals(0))
            {
                this._updownBet.Visible =
                    this._buttonAllIn.Visible =
                        false;
            }
            else
            {
                this.Action = Action.Call;
            }
        }

        public void ResetPlayerAfterStage(
            Stage theStage)
        {
            if (!this.Action.Equals(Action.Fold) &&
                !this.Action.Equals(Action.AllIn))
            {
                this.Action = Action.None;
                this.IsAvailable = true;
            }
            if (!theStage.Equals(Stage.None))
            {
                this.Stake = 0;
            }
        }

        public void ResetPlayerAfterGame()
        {
            this._labelName.ForeColor =
                this._labelAccount.ForeColor =
                this._labelStake.ForeColor =
                    Color.White; 
            
            this.Action = Action.None;
            this.IsAvailable = true;
            this.Stake = 0;
            this.Visible = true;
        }
        
        public void Enable()
        {
            this._buttonFold.Visible =
                this._updownBet.Visible =
                this._buttonAction.Visible =
                this._buttonAllIn.Visible =
                    true;
        }
        
        public void Disable()
        {
            this._buttonFold.Visible =
                this._updownBet.Visible =
                this._buttonAction.Visible =
                this._buttonAllIn.Visible =
                    false;
        }
        #endregion
        #endregion

        #region Events
        public event EventHandler OnFold;
        public event EventHandler OnCall;
        public event EventHandler OnCheck;
        public event EventHandler OnBet;
        public event EventHandler OnRaise;
        public event EventHandler OnAllIn;
        #endregion
    }
}
